import { u_getTypeof } from "@gd-accbuild-core/config/utils";
/**
 * 工具函数：树形结构扁平化(按顺序)
 */
export const util_GetFlattenTree = (source, treeProps = { childrenKeyAlias: "children", hasChildrenKebab: "has-children" }) => {
    if (!Array.isArray(source)) {
        return [];
    }
    const res = []
    const childrenKeyAlias = treeProps.childrenKeyAlias
    const fn = source => {
        source.forEach(el => {
            res.push(el)
            Array.isArray(el[childrenKeyAlias]) && el[childrenKeyAlias].length > 0 ? fn(el[childrenKeyAlias]) : null
        })
    }
    fn(source)
    return res
}

export const util_GetAllParentArr = (list, id, treeProps = { idKeyAlias: "id", childrenKeyAlias: "children" }) => {
    const idKeyAlias = treeProps.idKeyAlias;
    const childrenKeyAlias = treeProps.childrenKeyAlias;
    for (let i in list) {
        if (list[i][idKeyAlias] === id) {
            //查询到返回该数组对象
            return [list[i]];
        }
        if (list[i][childrenKeyAlias]) {
            let node = util_GetAllParentArr(list[i][childrenKeyAlias], id, treeProps);
            if (node !== undefined) {
                //查询到把父节点连起来
                return node.concat(list[i]);
            }
        }
    }
}
export const util_GetAllChildArr = (source, id, treeProps) => {
    const res = []
    return getChild(source, id, res, treeProps)
}
function getChild(nodes, id, arr, treeProps = { idKeyAlias: "id", childrenKeyAlias: "children" }) {
    const idKeyAlias = treeProps.idKeyAlias;
    const childrenKeyAlias = treeProps.childrenKeyAlias;
    for (let el of nodes) {
        if (el[idKeyAlias] === id) {
            console.log('匹配')
            arr.push(el);
            if (el[childrenKeyAlias]) {
                childNodesDeep(el[childrenKeyAlias], arr);
            }
        } else if (el[childrenKeyAlias]) {
            getChild(el[childrenKeyAlias], id, arr);
        }
    }
    return arr;
}
function childNodesDeep(nodes, arr, treeProps = { idKeyAlias: "id", childrenKeyAlias: "children" }) {
    const idKeyAlias = treeProps.idKeyAlias;
    const childrenKeyAlias = treeProps.childrenKeyAlias;
    if (nodes)
        nodes.forEach((ele) => {
            arr.push(ele);
            if (ele[childrenKeyAlias]) {
                childNodesDeep(ele[childrenKeyAlias], arr);
            }
        });
}

// ///////////////固定的工具方法//////////////////////////////////
/**
 * 可选链的hack: 判断obj.a.b.c 是否 不为 undefined 或 null 则返回,否则返回默认值
 * @param {object} obj 原始对象
 * @param {Array} attars 按层级次序的属性数组
 * @param {any} defaultVal 默认值
 * */
export const util_OptionChainHack = (obj, attrs, defaultVal) => {
    let curObj = { ...obj };
    for (let i = 0; i < attrs.length; i++) {
        const attr = attrs[i];
        curObj = curObj?.[attr];
    }
    return curObj ?? defaultVal;
}
/**
     * //TODO: 整表属性  事件激活属性可以不用,可以在具体事件方法中手写
     * 分为 事件激活属性、当前行属性、列通用属性;如果前者存在,则后者不会体现会被覆盖。
     * 设置当前行的属性值: 先继承列的通用属性,再用当前行具体属性去覆盖
     * @param {Number} rowNum
     * @param {object} obj 原始对象
     * @param {Array} attars 按层级次序的属性数组
     * @param {any} defaultVal 默认值
     */
export const util_GetRowAttrVal = (row, rowIdx, obj, attrs, defaultVal) => {
    // 读取继承属性
    const inheritAttrVal = util_OptionChainHack(obj, attrs, defaultVal);
    if (rowIdx === null) {
        return inheritAttrVal
    }
    // 读取当前行属性值
    let curRowAttrVal;
    const typeofStr = u_getTypeof(obj?.curRowAttrFunc);
    /* if (typeofStr === "function") {
        const componentRowAttrObj = obj?.curRowAttr({row, rowIdx});
        const curObj = { ...componentRowAttrObj };
        const [, ...curAttrs] = attrs;
        curRowAttrVal = util_OptionChainHack(curObj, curAttrs, undefined);
    } else if (typeofStr === "object") {
        const componentRowAttrObj = obj?.curRowAttr;
        const curObj = { ...componentRowAttrObj };
        const [, ...curAttrs] = attrs;
        curRowAttrVal = util_OptionChainHack(curObj, curAttrs, undefined);
    } else  */
    if (typeofStr === "string") {
        const componentRowAttrObj = new Function("configObj", obj.curRowAttrFunc)({ rowData: row, rowIdx, metaItem: obj });
        const curObj = { ...componentRowAttrObj };
        const [, ...curAttrs] = attrs;
        curRowAttrVal = util_OptionChainHack(curObj, curAttrs, undefined);
    } else {
        curRowAttrVal = util_GetRowDynmicAttrVal(
            row,
            rowIdx,
            obj,
            attrs,
            defaultVal,
            inheritAttrVal
        );
        /* if (attrs.length === 2 && attrs[1] === "readonly")
          console.log(curRowAttrVal, obj.key, row, rowIdx, obj); */
    }
    return curRowAttrVal ?? inheritAttrVal;
    // 读取当前行事件激活的属性值
    /* let eventActivedAttrVal;
    const everyRowActivedAttrIdxList = obj?.everyRowActivedAttrIdxList ?? [];
    // const everyRowActivedAttrIdxList = nullishCoalescingOperator(obj?.everyRowActivedAttrIdxList,[]);
    if (everyRowActivedAttrIdxList.length > 0) {
        const [, ...curAttrs] = attrs;
        eventActivedAttrVal = util_OptionChainHack(
            obj.activedAttrConstList[everyRowActivedAttrIdxList[rowIdx]],
            curAttrs,
            undefined
        );
    }
    return eventActivedAttrVal ?? curRowAttrVal ?? inheritAttrVal; */
}
/** 
 * 下拉选项每一行能更具不同的传值,获取对应行的下拉选项 
 */
const util_GetRowDynmicAttrVal = (row, rowIdx, obj, attrs, defaultVal, inheritAttrVal) => {
    if (u_getTypeof(inheritAttrVal) !== "object") {
        return inheritAttrVal
    }
    if (!inheritAttrVal.hasOwnProperty("defaultValue")) {
        return inheritAttrVal;
    } else if (inheritAttrVal.hasOwnProperty(rowIdx)) {
        return inheritAttrVal[rowIdx];
    } else if (inheritAttrVal.hasOwnProperty("defaultValue")) {
        return inheritAttrVal.defaultValue;
    } else {
        return defaultVal;
    }
}

const forcedInheritedAttrList = [{ disabled: true }, { readonly: true }, { size: "small" }];
/**
     * 先获取继承属性,如果继承属性的属性值为"强制类型",则子组件自带属性失效;否则若子组件存在自带属性,则子组件自带属性优先。
     * 有哪些属性为强制类型: disabled:true、readonly:true
     * 如:disabled、readonly 继承的disabled为true,则子组件的disabled失效
     */
export const util_GetCurComponentAttrWithInheritedAttr = (row, rowIdx, obj, attrs, defaultVal, commonAttr) => {
    let inheritedAttrVal = defaultVal;
    if (attrs.length === 2 && attrs[0] === "componentAttr") {
        inheritedAttrVal = util_GetRowAttrVal(
            row, rowIdx,
            commonAttr,
            [attrs[1]],
            defaultVal
        );
    }
    // 读取强制类型值

    const forcedKeyIdx = forcedInheritedAttrList.findIndex(
        (el, idx) =>
            Object.keys(el)[0] === attrs[1] && inheritedAttrVal === el[attrs[1]]
    );
    let forcedInheritedAttrVal;
    if (forcedKeyIdx >= 0) {
        forcedInheritedAttrVal =
            forcedInheritedAttrList[forcedKeyIdx][attrs[1]];
    }
    // 如果强制类型值存在,则后面子组件属性失效
    return (
        forcedInheritedAttrVal ??
        util_GetRowAttrVal(row, rowIdx, obj, attrs, inheritedAttrVal)
    );
}

/**
 * 根据元数据获取表单重置的值
 *  */
export const resetFormData = (formData, formItemMetaList, defaultValMap = {}) => {
    formItemMetaList.forEach((metaItem) => {
        const key = metaItem.key
        const formItemMeta = formItemMetaList.find(el => el.key === key)
        const defaultVal = defaultValMap?.[key] ?? (formItemMeta?.default ?? null)
        const getResetVal = () => {
            if (formItemMeta.type === "Switch" || formItemMeta?.componentAttr?.type === "boolean") {
                return false
            } else {
                return undefined
            }
        }
        formData[key] = ![null, undefined].includes(defaultVal) ? defaultVal : getResetVal()
    })
}

/**
 * 根据元数据获取表单转换的值
 * @param {object} defaultValMap 强制默认映射
 *  */
export const transFormData = (formData, formItemMetaList, defaultValMap = {}) => {
    formItemMetaList.forEach((metaItem) => {
        const key = metaItem.key
        const defaultVal = defaultValMap?.[key] ?? null
        const formItemMeta = formItemMetaList.find(el => el.key === key)
        const getTransVal = () => {
            if (formItemMeta.type === "Switch" || formItemMeta.dataType === "boolean") {
                return ["true", true].includes(formData[key])
            } else if (["int", "number"].includes(formItemMeta.dataType)) {
                return +formData[key]
            } else {
                return formData[key]
            }
        }
        formData[key] = defaultVal !== null ? defaultVal : getTransVal()
    })
    return formData
}